package com.vgooo.util;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.HashMap;

import net.tsz.afinal.FinalBitmap;
import net.tsz.afinal.FinalHttp;
import net.tsz.afinal.http.AjaxCallBack;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.text.Html;
import android.text.StaticLayout;
import android.util.Log;
import android.view.View;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;
import android.widget.TextView;

import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.PauseOnScrollListener;
import com.nostra13.universalimageloader.core.assist.SimpleImageLoadingListener;
import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;
import com.vgooo.client.Constants;
import com.vgooo.client.Main;
import com.vgooo.client.R;
import com.vgooo.client.VGApplication;

public class BitmapUtils {

	public static final String imageCachesPath = VGApplication.getCaesPath()
			+ "/images/";// 图片缓存路径
	private static HashMap<String, BitmapRef> caches;// 位图内存软引用集合
	private static ReferenceQueue<Bitmap> cachesRef ;//使用ReferenceQueue清除失去了软引用对象的SoftReference
	static {
		caches = VGApplication.getCaches();
		cachesRef = VGApplication.cachesRef;
	}
	
	public final static ImageLoader imageLoader = ImageLoader.getInstance();
	public final static DisplayImageOptions options = new DisplayImageOptions.Builder().showStubImage(R.drawable.image_default)
			.showImageForEmptyUri(R.drawable.image_default)
			.showImageOnFail(R.drawable.image_default)
			.cacheInMemory()
			.cacheOnDisc()
			.displayer(new RoundedBitmapDisplayer(0))
			.build();
	
	public final static OnScrollListener  onScrollListener= new PauseOnScrollListener(BitmapUtils.imageLoader, false, false);
	
	public final static SimpleImageLoadingListener animateFirstListener = new  SimpleImageLoadingListener() {
			@Override
			public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
				if (loadedImage != null) {
					ImageView imageView = (ImageView) view;				
					imageView.setImageBitmap(loadedImage);
				}
			}
		};
	/**
	 * 从字节流中获取位图
	 * 
	 * @param data
	 * @return
	 */
	public static Bitmap getBitmap(byte[] data) {
		return BitmapFactory.decodeByteArray(data, 0, data.length);
	}

	/**
	 * 从字节输入流中获取位图
	 * 
	 * @param in
	 *            字节输入流
	 * @return bitmap 位图
	 */
	public static Bitmap getBitmap(InputStream in) {
		Bitmap bm = null;
		try {
			bm = BitmapFactory.decodeStream(in);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return bm;
	}

	/**
	 * 从指定文件路径获取位图
	 * 
	 * @param path
	 *            文件路径
	 * @return bitmap 位图
	 */
	public static Bitmap getBitmap(String path) {
		return BitmapFactory.decodeFile(path);
	}

	/**
	 * 从字节流中获取位图，并对文图按照比例进行缩放
	 * 
	 * @param in
	 *            自己输入流
	 * @param scale
	 *            缩放比例
	 * @return bitmap 位图
	 */
	public static Bitmap getBitmap(InputStream in, int scale) {
		Bitmap bm = null;
		try {
			Options opts = new Options();
			opts.inSampleSize = scale;
			bm = BitmapFactory.decodeStream(in, null, opts);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return bm;

	}

	/**
	 * 从字节数组中获取位图，并按比例缩放
	 * 
	 * @param data
	 *            字节数组
	 * @param scale
	 *            缩放比例
	 * @return bitmap 位图
	 */
	public static Bitmap getBitmap(byte[] data, int scale) {
		Bitmap bm = null;
		Options opts = new Options();
		opts.inSampleSize = scale;
		bm = BitmapFactory.decodeByteArray(data, 0, data.length, opts);
		return bm;
	}

	/**
	 * 从字节流中获取位图，并按指定的宽高进行缩放
	 * 
	 * @param data
	 *            字节数组
	 * @param width
	 *            指定的宽度
	 * @param height
	 *            指定的高度
	 * @return bitmap 位图
	 */
	public static Bitmap getBitmap(byte[] data, int width, int height) {
		Bitmap bm = null;
		Options opts = new Options();
		opts.inJustDecodeBounds = true;
		bm = BitmapFactory.decodeByteArray(data, 0, data.length, opts);
		int x = opts.outWidth / width;
		int y = opts.outHeight / height;
		int scale = x > y ? x : y;
		bm = getBitmap(data, scale);
		return bm;
	}

	/**
	 * 从资源网络路径截取资源名
	 * 
	 * @param urlPath
	 *            网络路径
	 * @return name 资源名
	 */
	public static String getImageName(String urlPath) {
		// log("urlPath = " + urlPath) ;
		if (urlPath == null || "".equals(urlPath)) {
			return "";
		} else {
			StringBuffer sb = new StringBuffer(urlPath);
			int index = sb.lastIndexOf("/");
			// log("index = " + index + "  urlPath = "+ urlPath );
			String fileName = sb.substring(index + 1);
			String str = sb.substring(index - 1, index);
			while ("/".equals(str)) {
				str = sb.substring(--index - 1, index);
			}
			return str + fileName;
		}
	}

	/**
	 * 获取缓存中的图片（先从软引用中获取，如果没有在从文件缓存中获取）
	 * 
	 * @param imageName
	 *            图片名称
	 * @return boolean ture：成功获取 false：获取失败
	 */
	public static boolean setBitmap(String urlPath, ImageView imageView) {
		String imageName = getImageName(urlPath);
		String path = imageCachesPath + imageName;
		Bitmap bm = null;
		// 判断缓存集合中是否存在该路径的图片缓存
		if (caches.containsKey(urlPath)) {
			bm = caches.get(urlPath).get();
			if (bm != null) {
				setImage(imageView, bm);
				log("从内存软引用用中取出位图：" + BitmapUtils.getImageName(urlPath));
				return true;
			} else {
				caches.remove(path);
			}
		}

		// 从文件中获取位图
		bm = BitmapFactory.decodeFile(path);
		// 判断文件缓存中是否存在该图片
		if (bm != null) {
			log("从文件用中取出位图：" + BitmapUtils.getImageName(urlPath));
			// 若存在文件中，同时将位图缓存到内存软引用
			if (!caches.containsKey(urlPath)) {
				saveImageSoftReference(urlPath, bm);
			}
			setImage(imageView, bm);
			return true;
		}

		// 如果内存软引用和文件中都没有缓存图片，先返回false
		return false;
	}

	/**
	 * 获取缓存中的图片（先从软引用中获取，如果没有在从文件缓存中获取）
	 * 
	 * @param imageName
	 *            图片名称
	 * @return boolean ture：成功获取 false：获取失败
	 */
	public static boolean setBitmap(String urlPath, View view) {
		String imageName = getImageName(urlPath);
		String path = imageCachesPath + imageName;
		Bitmap bm = null;
		// 判断缓存集合中是否存在该路径的图片缓存
		if (caches.containsKey(urlPath)) {
			bm = caches.get(urlPath).get();
			if (bm != null) {
				// Drawable drawable = new BitmapDrawable(bm);
				setView(view, bm);
				log("从内存软引用用中取出位图：" + BitmapUtils.getImageName(urlPath));
				return true;
			} else {
				caches.remove(path);
			}
		}

		// 从文件中获取位图
		bm = BitmapFactory.decodeFile(path);
		// 判断文件缓存中是否存在该图片
		if (bm != null) {
			log("从文件用中取出位图：" + BitmapUtils.getImageName(urlPath));
			// 若存在文件中，同时将位图缓存到内存软引用
			if (!caches.containsKey(urlPath)) {
				saveImageSoftReference(urlPath, bm);
			}
			setView(view, bm);
			return true;
		}

		// 如果内存软引用和文件中都没有缓存图片，先返回false
		return false;
	}

	/**
	 * 设置ImageView的图片
	 * 
	 * @param imageView
	 * @param bitmap
	 */
	public static void setImage(ImageView imageView, Bitmap bitmap) {
		imageView.setImageBitmap(bitmap);
		bitmap = null ;
//		recycledBitmap(bitmap);
	}

	/**
	 * 设置View的背景图片
	 * 
	 * @param view
	 * @param bitmap
	 */
	public static void setView(View view, Bitmap bitmap) {
		view.setBackgroundDrawable(new BitmapDrawable(bitmap));
	}

	/**
	 * 将网络图片缓存在内存的软引用中
	 * 
	 * @param urlPath
	 *            图片网络路径
	 * @param bitmap
	 *            位图
	 */
	public static void saveImageSoftReference(String urlPath, Bitmap bm) {
		if (bm != null && urlPath != null) {
			log("将位图：" + BitmapUtils.getImageName(urlPath) + "放入软引用");
			BitmapRef bRef = new BitmapUtils.BitmapRef(bm) ;
			bRef.setUrlPath(urlPath);
			caches.put(urlPath, bRef);
		}
	}

	/**
	 * 将图片缓存在软引用和本地
	 * 
	 * @param name
	 *            图片名
	 * @param bm
	 *            图片
	 * @throws IOException
	 */

	public static void save(String urlPath, Bitmap bm) throws IOException {
		FileOutputStream out = null;
		BufferedOutputStream bos = null;
		try {
			String name = getImageName(urlPath);
			String savePath = imageCachesPath + name;
			log("imageCachesPath = " + imageCachesPath);
			log("savePath = " + savePath);
			if (bm != null && savePath != null) {
				// 先缓存在软引用中
				saveImageSoftReference(urlPath, bm);
				File file = new File(savePath);
				if (!file.getParentFile().exists()) {
					file.getParentFile().mkdirs();
				}
				if (!file.exists())
					file.createNewFile();

				out = new FileOutputStream(file);
				bos = new BufferedOutputStream(out);
				log("将位图：" + BitmapUtils.getImageName(urlPath) + "缓存在文件中");
				bm.compress(CompressFormat.JPEG, 100, bos);

			}
		} finally {
			if (bos != null) {
				try {
					bos.close();
				} catch (Exception e) {
				}
				
				if (out != null) {
					try {
						out.close();
					} catch (Exception e) {
						// TODO: handle exception
					}

				}
			}
		}
	}
	/**
	 * 清除图片在内存引用中的缓存
	 */
	public static void cleanCache(){
		if(caches==null||caches.isEmpty()){
			return ;
		}
		BitmapRef  bRef = null ;
		while((bRef = (BitmapRef) cachesRef.poll())!= null){
			caches.remove(bRef.getUrlPath());
		}
		if(caches.size() >20){
			caches.clear() ;
		}
		//System.gc() ;
		System.runFinalization();
		
	}
	
	public static class BitmapRef extends SoftReference<Bitmap>{
		private String urlPath ;
		public BitmapRef(Bitmap bm) {
			super(bm,cachesRef);
			// TODO Auto-generated constructor stub
		}
		
		
		public BitmapRef(Bitmap bm, ReferenceQueue<? super Bitmap> q) {
			super(bm, q);
			// TODO Auto-generated constructor stub
		}


		public String getUrlPath() {
			return urlPath;
		}
		public void setUrlPath(String urlPath) {
			this.urlPath = urlPath;
		}
		
		
	}
	
	
	/**
	 * 回收ImageView设置图片所占用的内存
	 * @param view
	 */
	public static void recycleImageView(ImageView view){
		Bitmap bm = view.getDrawingCache(true);
		view.setImageResource(R.drawable.bg_transparent);
//		recycledBitmap(bm);
		view = null ;
	}
	
	/**
	 * 释放Bitmap内存
	 * @param bm
	 */
	public static void recycledBitmap(Bitmap bm){
		if(bm!=null&&!bm.isRecycled()){
			bm.recycle();
			bm = null ;
		}
	}
	

	/**
	 * 打印日志信息
	 * 
	 * @param info
	 */
	private static void log(String info) {
//		 Log.i("BitmapUtils", info);
//		DebugTools.log("BitmapUtils", info);
	}

	
//	public static void loaderImage(String urlPath ,ImageView imageView){
//		Main.picLading.LoadImage(imageView, urlPath);
//	}
	
	// public final static
	public static void loaderImage(String urlPath, ImageView imageView,
			Context context) {
		imageLoader.displayImage(urlPath, imageView, options, animateFirstListener);
		if(true){
			return ;
		}
		
		//以下代码不会执行
		imageView.setImageResource(R.drawable.image_default);
		boolean flag = BitmapUtils.setBitmap(urlPath, imageView);
		if (!flag) {
			log("首次加载:" + BitmapUtils.getImageName(urlPath) + "图片，从网络下载");
			ImageLoaderTask task = new ImageLoaderTask(urlPath, imageView,
					context);
			AsyncImageLoader loder = new AsyncImageLoader();
			try {
				loder.execute(task);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				// throw new RuntimeException("下载网络图片失败：" + urlPath);
				UmengUtils.onError(context, e.toString());
			}
		} else {
			log("从缓存中加载:" + BitmapUtils.getImageName(urlPath) + "图片");
		}
	}

	public static void loaderImage(String urlPath, ImageView imageView,
			Context context, Handler handler) {
		boolean flag = BitmapUtils.setBitmap(urlPath, imageView);
		if (!flag) {
			log("首次加载:" + BitmapUtils.getImageName(urlPath) + "图片，从网络下载");
			sendLoading(handler);
			ImageLoaderTask task = new ImageLoaderTask(urlPath, imageView,
					context, handler);
			AsyncImageLoader loder = new AsyncImageLoader();
			try {
				loder.execute(task);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				// throw new RuntimeException("下载网络图片失败：" + urlPath);
				UmengUtils.onError(context, e.toString());
			}
		} else {
			log("从缓存中加载:" + BitmapUtils.getImageName(urlPath) + "图片");
			sendLoadSuccess(handler);
		}
	}

	public static void loaderImage(String urlPath, View view, Context context) {
		boolean flag = BitmapUtils.setBitmap(urlPath, view);
		if (!flag) {
			log("******首次加载:" + BitmapUtils.getImageName(urlPath) + "图片，从网络下载");
			ImageLoaderTask task = new ImageLoaderTask(urlPath, view, context);
			AsyncImageLoader loder = new AsyncImageLoader();
			try {
				loder.execute(task);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				// throw new RuntimeException("****下载网络图片失败：" + urlPath);
				UmengUtils.onError(context, e.toString());
			}
		} else {
			log("*****从缓存中加载:" + BitmapUtils.getImageName(urlPath) + "图片");
		}
	}

	public static void sendLoadSuccess(Handler handler) {
		handler.sendEmptyMessage(Constants.LOAD_SUCCESS);
	}

	public static void sendLoadFail(Handler handler) {
		handler.sendEmptyMessage(Constants.LOAD_FAIL);
	}

	public static void sendLoading(Handler handler) {
		handler.sendEmptyMessage(Constants.LOAD_ISLOADING);
	}

	
	public  static PictureLoadingThreadPool albumLoadPool ;//= new PictureLoadingThreadPool(Main.activity, 5);
	
	/**
	 * 图片下载线程池
	 * 
	 * @author Administrator
	 * 
	 */
	public static class PictureLoadingThreadPool {
		private Context context;
		FinalBitmap finalBitmap;
		private int threadCounts = Integer.MAX_VALUE;
		private String cachPath ;
		

		
		
		
		
		public PictureLoadingThreadPool(Context context, String cachPath) {
			super();
			this.context = context;
			this.cachPath = cachPath;
			this.context = context;
			this.threadCounts = threadCounts;
			this.cachPath = cachPath;
			finalBitmap = new FinalBitmap(context);
			finalBitmap.configBitmapMaxWidth(DensityUtil.dip2px(context, 320));
			finalBitmap.configBitmapLoadThreadSize(threadCounts);
			finalBitmap.configLoadingImage(R.drawable.bg_transparent);
			finalBitmap.configDiskCachePath(imageCachesPath + this.cachPath);
			finalBitmap.init();
		}


		public PictureLoadingThreadPool(Context context, int threadCounts,
				String cachPath) {
			super();
			this.context = context;
			this.threadCounts = threadCounts;
			this.cachPath = cachPath;
			finalBitmap = new FinalBitmap(context);
			finalBitmap.configBitmapMaxWidth(DensityUtil.dip2px(context, 320));
			finalBitmap.configBitmapLoadThreadSize(threadCounts);
			finalBitmap.configLoadingImage(R.drawable.bg_transparent);
			finalBitmap.configDiskCachePath(imageCachesPath + this.cachPath);
			finalBitmap.init();
		}

		public PictureLoadingThreadPool(Context context) {
			super();
			this.context = context;
			finalBitmap = new FinalBitmap(context);
			finalBitmap.configBitmapMaxWidth(DensityUtil.dip2px(context, 320));
			finalBitmap.configBitmapLoadThreadSize(threadCounts);
			finalBitmap.configLoadingImage(R.drawable.bg_transparent);
			finalBitmap.configDiskCachePath(imageCachesPath + "fb_default/");
			finalBitmap.init();
		}

		public PictureLoadingThreadPool(Context context, int threadCounts) {
			super();
			this.context = context;
			this.threadCounts = threadCounts;
			finalBitmap = new FinalBitmap(context);
//			finalBitmap.configBitmapMaxWidth(DensityUtil.dip2px(context, 320));
			finalBitmap.configBitmapLoadThreadSize(threadCounts);
			finalBitmap.configLoadingImage(R.drawable.bg_transparent);
			finalBitmap.configDiskCachePath(imageCachesPath + "fb/");
			finalBitmap.init();
		}
		
		public void setCachPaht(String cachPath){
			finalBitmap.configDiskCachePath(cachPath);
		}
		

		public void setThreadCounts(int threadCounts) {
			this.threadCounts = threadCounts;
			finalBitmap.init();
		}

		public void LoadImage(ImageView imageView, String url) {
			finalBitmap.display(imageView, url);
		}

		public void exit() {
			finalBitmap.setExitTasksEarly(true);
			finalBitmap.onDestroy() ;
		}

	}

	
}
